/*
  Ce fichier comprend l'ensemble des fonctions intermédiaires nécessaires à l'analyse de fréquence.
  L'analyse est ensuite effectuer dans des main différents pour chaque type de décryptage.
*/


#include <stdlib.h>
#include <stdio.h>
#include "header.h"


/*
  freqT represente la repartition des lettres dans la langue française. 
  Ex : la lettre 'a' est présente à hauteur de 8.25% et le 'e' à hauteur de 17.75%
  Les frequences qui suivent le 'z' sont les fréquences des binomes de lettre consécutives
  Dans cet ordre  : 

*/
float freqT[26] = {8.25, 1.25, 3.25, 3.75, 17.75, 1.25, 1.25, 1.25, 7.25, 0.75, 0.00, 5.75, 3.25, 7.25, 5.75, 3.75, 1.25, 7.25, 8.25, 7.25, 6.25, 1.75, 0.00, 0.00, 0.75, 0.00};

/*
  Frequence des bigrammes. Les bigrammes dont la fréquence est > 0 sont (ordre décroissants) :
  ss - ee - ll - tt - nn - mm - rr - pp - ff - cc - aa - uu - ii
*/
float freqT_bigrams[26] = {0.03, 0.00, 0.03, 0.00, 0.66, 0.08, 0.00, 0.00, 0.01, 0.00, 0.00, 0.29, 0.17, 0.20, 0.00, 0.10, 0.00, 0.16, 0.73, 0.24, 0.02, 0.00, 0.00, 0.00, 0.00, 0.00};


/*
  frequence calcule la fréquence d'apparition des lettres dans un texte crypté selon un cryptage monoalphabétique (de type 
  chiffre de César)

  @param txt : tableau d'entier représentant le texte codé
  @param taille : taille de txt
  
  @result : float* c'est le tableau de répartition des fréquences pratiques freqP en %
*/
void frequencies(int* txt, int taille, float* freqP, float* freqP_b)
{
  int i = 0;
  for (int j = 0; j < MAX_NUMBER_OF_CHILDREN; j++)
    {
      freqP[j] = 0.0;
      freqP_b[j] = 0.0;
    }
  while (i < taille-1)
    {
      freqP[txt[i]]++;
      if(txt[i] == txt[i+1])
	{
	  freqP_b[txt[i]]++; 
	}
      i++;
    }
  freqP[txt[i]]++;
  for(int j = 0; j < MAX_NUMBER_OF_CHILDREN; j++)
    {
      freqP[j] = (freqP[j] / taille)*100;
      freqP_b[j] = (freqP_b[j] / taille)*100;
    }
}


/*
  Fonction booleenne permettant de savoir si la lettre 'i' a déjà été identifié.

  @param i : valeur à tester
  @param ID : Tableau d'identification

  @result 1 si la lettre i a déjà été identifié (ie. Il existe un j tel que ID[j] == i <=> i correspond à une lettre du texte crypté pour laquelle nous connaisson une correspondance). 0 sinon.
*/
int is_identified(int i, int* ID)
{
  int bool = 0, j = 0;
  while (j < 26 && bool == 0)
    {
      if (ID[j] == i)
	{
	  bool = 1;
	}
      j++;
    }
  return bool;
}





/*
  Fonction de calcul de la prochaine lettre à proposer à l'identification. Cette lettre est la lettre la plus fréquente 
  dans le texte crypté dont on ne connait toujours pas sa signification (ie. Il n'existe aucun i tel que ID[i] == result)

  @param freqP : Tableau des fréquences pratiques
  @param ID : Tableau d'identification

  @result : indice de la prochaine lettre non identifiée à fréquence maximale. -1 si aucune lettre n'est proposable.
*/
int next_proposition(float* freqP, int* ID)
{
  int imax = 0, flag = 0, i = 0;
  while((i < 26) && !flag)
    {
      if(!(is_identified(i,ID)))
	{
	  flag = 1;
	}
      else
	{
	  i++;
	}
    }
  /*
    Au moins un élément n'a pas été identifié. Le premier est celui d'incide i (état indéterminé pour j > i)
  */
  if(flag)
    {
      imax = i;
      /*
	Sélection de l'élément non identifié à fréquence maximale
      */
      for(int j = imax+1; j < 26; j++)
	{
	  if((!(is_identified(j, ID))) && (freqP[imax] <= freqP[j]))
	    {
	      imax = j;
	    }
	}
    }
  /*
    Tous les éléments ont été identifié, le tableau ID est plein.
  */
  else
    {
      imax = -1;
    }
  return imax;
}



float th_frequency(int c)
{
  return freqT[c];
}

float th_frequency_b(int bigram)
{
  return freqT_bigrams[bigram];
}

int exist_match(int* bigrams, int* p)
{
  return( (bigrams[0]==p[0]) || (bigrams[0]==p[1]) || (bigrams[1]==p[0]) || (bigrams[1]==p[1]) );
}


int match_bigram(int* p, int* bigrams, float* freqP_b)
{
  int res = 4; 
  int cpt = 0;
  int aff_b0 = 0;
  int aff_b1 = 0;

  if (p[0] == bigrams[0])
    {
      res--;
      cpt++;
      aff_b0 = 1; //On a pris en compte bigrams[0]
      printf("(%d) %c (fréquence dans la langue française : %.2f%%, fréquence du bigramme %.2f%%)\n",cpt, int_to_char(p[0], 1), th_frequency(p[0]), th_frequency_b(bigrams[0]));
    }
  else
    {
      if(p[0] == bigrams[1])
	{
	  res--;
	  cpt++;
	  aff_b1 = 1; // On a pris en compte bigrams[1]
	  printf("(%d) %c (fréquence dans la langue française : %.2f%%, fréquence du bigramme %.2f%%)\n",cpt, int_to_char(p[0], 1), th_frequency(p[0]), th_frequency_b(bigrams[1]));
	}
      else
	{
	  cpt++;
	  printf("(%d) %c (fréquence dans la langue française : %.2f%%)\n", cpt, int_to_char(p[0], 1), th_frequency(p[0]));
	}
    }

  if(p[1] == bigrams[0])
    {
      res--;
      cpt++;
      aff_b0 = 1; // On a pris en compte bigrams[0]
      printf("(%d) %c (fréquence dans la langue française : %.2f%%, fréquence du bigramme %.2f%%)\n",cpt, int_to_char(p[1], 1), th_frequency(p[1]), th_frequency_b(bigrams[0]));
    }
  else
    {
      if(p[1] == bigrams[1])
	{
	  res--;
	  cpt++;
	  aff_b1 = 1; // On a pris en compte bigrams[1]
	  printf("(%d) %c (fréquence dans la langue française : %.2f%%, fréquence du bigramme %.2f%%)\n",cpt, int_to_char(p[1], 1), th_frequency(p[1]), th_frequency_b(bigrams[1]));
	}
      else
	{
	  cpt++;
	  printf("(%d) %c (fréquence dans la langue française : %.2f%%)\n", cpt, int_to_char(p[1], 1),  th_frequency(p[1]));
	}
    }     
  if(! aff_b0)
    {
      cpt ++;
      printf("(%d) %c (fréquence dans la langue française : %.2f%%, fréquence du bigramme %.2f%%)\n", cpt, int_to_char(bigrams[0], 1), th_frequency(bigrams[0]), th_frequency_b(bigrams[0]));
    }
  if(! aff_b1)
    {
      cpt++;
      printf("(%d) %c (fréquence dans la langue française : %.2f%%, fréquence du bigramme %.2f%%)\n", cpt, int_to_char(bigrams[1], 1), th_frequency(bigrams[1]), th_frequency_b(bigrams[1]));
    }
  return res;
}
